<?php

/**
 * 协程：适合 IO密集型应用
 */
class Coroutine
{
    public function test1()
    {
        go(function () {
            //Co::sleep(1);
            echo "hello go1 \n";
        });

        echo "hello main \n";

        go(function () {
            echo "hello go2 \n";
        });
    }

    /**
     * 同步版
     * @return void
     */
    public function normal()
    {
        $n = 4;
        for ($i = 0; $i < $n; $i++) {
            sleep(1);
            echo microtime(true) . ": hello $i \n";
        }
        echo "hello main \n";
    }

    /**
     * 单机协程版：只有一个协程, 并没有使用到协程调度减少 IO 阻塞
     * @return void
     */
    public function singleCo()
    {
        $n = 4;
        go(function () use ($n) {
            for ($i = 0; $i < $n; $i++) {
                Co::sleep(1);
                echo microtime(true) . ": hello $i \n";
            }
        });
        echo "hello main \n";
    }

    /**
     * 多协程版：真正使用到协程调度带来的 IO 阻塞时的调度
     * @return void
     */
    public function multiCo()
    {
        $n = 4;
        for ($i = 0; $i < $n; $i++) {
            go(function () use ($i) {
                //Co::sleep(1); //Co::sleep() 模拟的是 IO密集型(请求)任务, 会引发协程的调度
                sleep(1); //sleep() 可以看做是 CPU密集型(运算)任务, 不会引起协程的调度
                echo microtime(true) . ": hello $i \n";
            });
        }
        echo "hello main \n";
    }

    public function multiCoRedis()
    {
        $n = 4;
        for ($i = 0; $i < $n; $i++) {
            go(function () use ($i) {
                $redis = new Co\Redis();
                $redis->connect('103.23.46.74', 6379);
                $redis->auth('Aa123456');
                $val = $redis->get('test-co');
                echo microtime(true) . ": $val \n";
            });
        }
        echo "hello main \n";
    }
}

$co = new Coroutine();
//$co->test1();
//$co->normal();
//$co->singleCo();
//$co->multiCo();
$co->multiCoRedis();